import { FrameCollection } from "./FrameCollection";
import { TraceStackFrame } from "./TraceStackFrame";
import { TraceFormatter } from "./defaultFormatter";

export class TraceCollection extends FrameCollection<TraceStackFrame> {
    /**
     * @description: 从当前的集合当中过滤符合条件的栈帧。
     * @param {Function} callbackFn 用来测试数组中每个元素的函数。返回 `true` 表示该元素通过测试，保留该元素， `false` 则不保留。它接受以下三个参数：
     * - `element` 数组中当前正在处理的元素。
     * - `index` 正在处理的元素在数组中的索引。
     * - `array` 调用了 `filter()` 的数组本身。
     * @return {LogCollection} 过滤出的符合条件的栈帧组成的新栈帧集合。
     */
    public filter(callbackFn: (frame: TraceStackFrame, index: number, array: TraceStackFrame[]) => boolean): TraceCollection {
        let result = new TraceCollection();
        let tempFrame: TraceStackFrame;

        for (let i = 0; i < this.frames.length; i++) {
            tempFrame = this.frames[i];
            if (callbackFn(tempFrame, i, this.frames)) {
                result.push(tempFrame);
            }
        }

        return result;
    }

    /**
     * @description: 将调用堆栈集合逐个转换为字符串。
     * @param {TraceFormatter} [format] 用于规定转换后的字符串格式的回调方法，默认转换格式的默认转换格式类似 Python 。
     * @return {string[]} 将集合中元素转换为字符串后的数组。
     */
    public toStringArray(format?: TraceFormatter): string[] {
        let trace: string[] = []

        for (let frame of this.frames) {
            trace.push(frame.toString(format));
        }

        return trace
    }

    /**
     * @description: 将调用堆栈集合转换为字符串。
     * @param {TraceFormatter} [format] 用于规定转换后的字符串格式的回调方法，默认转换格式的默认转换格式类似 Python 。
     * @return {string} 转换后的字符串。
     */
    public toString(format?: TraceFormatter): string {
        let trace: string[] = []

        for (let frame of this.frames) {
            trace.push(frame.toString(format));
        }

        return trace.join("\n")
    }
}